package com.kongjs.application.controller.rest;

import com.kongjs.application.annotation.OperationLogging;
import com.kongjs.application.convert.RolesConverter;
import com.kongjs.application.enums.OperationName;
import com.kongjs.application.enums.OperationType;
import com.kongjs.application.model.dto.*;
import com.kongjs.application.model.vo.*;
import com.kongjs.application.service.IRolesService;
import com.kongjs.application.util.PageUtil;
import com.kongjs.application.util.TreeUtil;
import com.kongjs.common.rest.annotation.Rest;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Rest
@RestController
@RequestMapping("/roles")
public class RolesController {

    @Resource
    private RolesConverter rolesConverter;
    @Resource
    private IRolesService rolesService;

    @PreAuthorize("hasAuthority('api:role:save:one')")
    @PostMapping
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.SAVE_ONE)
    public boolean save(@RequestBody @Validated SaveRoleVO vo) {
        SaveRoleDTO dto = rolesConverter.toDto(vo);
        return rolesService.save(dto);
    }

    @PreAuthorize("hasAuthority('api:role:remove:one')")
    @DeleteMapping("/{id}")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.REMOVE_ONE)
    public boolean remove(@PathVariable("id") Long id) {
        return rolesService.remove(id);
    }

    @PreAuthorize("hasAuthority('api:role:update:one')")
    @PutMapping("/{id}")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.UPDATE_ONE)
    public boolean update(@PathVariable("id") Long id, @RequestBody @Validated UpdateRoleVO vo) {
        UpdateRoleDTO dto = rolesConverter.toDto(vo);
        dto.setId(id);
        return rolesService.update(dto);
    }

    @PreAuthorize("hasAuthority('api:role:update:one')")
    @PatchMapping("/{id}")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.UPDATE_ONE)
    public boolean updatePart(@PathVariable("id") Long id, @RequestBody UpdateRoleVO vo) {
        UpdateRoleDTO dto = rolesConverter.toDto(vo);
        dto.setId(id);
        return rolesService.update(dto);
    }

    @PreAuthorize("hasAuthority('api:role:query:one')")
    @GetMapping("/{id}")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.QUERY_ONE,recordResponse = false)
    public QueryRoleVO query(@PathVariable("id") Long id) {
        QueryRoleDTO dto = rolesService.query(id);
        return rolesConverter.toVo(dto);
    }

    @PreAuthorize("hasAuthority('api:role:query:list')")
    @GetMapping
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.QUERY_LIST,recordResponse = false)
    public List<QueryRoleVO> list() {
        List<QueryRoleDTO> dtos = rolesService.queryList();
        return rolesConverter.toVos(dtos);
    }

    @PreAuthorize("hasAuthority('api:role:query:page')")
    @GetMapping("/page")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.QUERY_PAGE,recordResponse = false)
    public PageVO<QueryRoleVO> page(@Validated PageQueryVO vo, QueryRoleParamVO paramVO) {
        PageQueryDTO dto = new PageQueryDTO();
        dto.setPageNum(vo.getPageNum());
        dto.setPageSize(vo.getPageSize());
        QueryRoleParamDTO paramDTO = rolesConverter.toDto(paramVO);
        PageDTO<QueryRoleDTO> pageDTO = rolesService.page(dto, paramDTO);
        List<QueryRoleVO> vos = rolesConverter.toVos(pageDTO.getItems());
        return PageUtil.pageVo(pageDTO, vos);
    }

    @PreAuthorize("hasAuthority('api:role:query:list') || hasAuthority('api:role:query:tree')")
    @GetMapping("/trees")
    @OperationLogging(operationName = OperationName.ROLE, operationType = OperationType.QUERY_TREE,recordResponse = false)
    public List<QueryRoleVO> trees() {
        List<QueryRoleDTO> dtos = rolesService.trees();
        List<QueryRoleVO> vos = rolesConverter.toVos(dtos);
        return TreeUtil.buildTree(vos);
    }
}
